#!/usr/bin/env python3
"""
Demo script showing how to use the independent monitoring server with react_terminal
This demonstrates the loosely coupled design where monitoring is completely separate
"""

import asyncio
import sys
import os
import threading
import time

# Add parent directory to path
try:
    parent_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    sys.path.append(parent_dir)
    from base_code import *
    from base_code.common import *
except ImportError:
    print("Error: Cannot find 'base_code' module. Please ensure pocketflow code is in correct path.")

# Import the independent monitor server
from monitor_server import start_monitor_server, get_monitor

# Import react_terminal components
try:
    from react_agent import ReActAgent
    from local_tools import GLOBAL_TOOL_SYSTEM
except ImportError as e:
    print(f"Error importing react modules: {e}")
    sys.exit(1)

async def demo_with_monitoring():
    """Demo showing how to use the monitoring server independently"""

    print("=" * 60)
    print("AgentMemory Monitor Demo - Loosely Coupled Design")
    print("=" * 60)
    print()

    # Step 1: Start the independent monitoring server
    print("Step 1: Starting independent monitoring server...")
    monitor, server_thread = start_monitor_server(host="0.0.0.0", port=8000)
    print(f"Monitor server started on port 8000")
    print(f"Web interface available at: http://localhost:8000")
    print()

    # Wait a moment for server to start
    await asyncio.sleep(2)

    # Step 2: Create ReActAgent (no monitoring integration needed)
    print("Step 2: Creating ReActAgent (no monitoring modifications needed)...")
    agent = ReActAgent(
        tools_system=GLOBAL_TOOL_SYSTEM,
        local_llm="qwen3:4b",
        remote_llm="qwen3-plus"
    )
    print("ReActAgent created successfully")
    print()

    # Step 3: Connect agent memory to monitor (this is the only connection point)
    print("Step 3: Connecting agent memory to monitor...")
    monitor.connect_agent_memory(agent.memory)
    print("AgentMemory connected to monitor")
    print()

    # Step 4: Run some tasks and monitor them
    print("Step 4: Running tasks with monitoring...")
    print("Monitor the web interface at: http://localhost:8000")
    print()

    test_tasks = [
        "What is 2 + 2?",
        "List the files in the current directory",
        "Read the first page of any PDF file if available"
    ]

    for i, task in enumerate(test_tasks, 1):
        print(f"Task {i}: {task}")
        print("-" * 40)

        try:
            # Process the task
            result = await agent.process_command_async(task)
            print(f"Result: {result}")

            # Show memory state (optional)
            agent.show_memo(verbose=False)

            # Record a custom event in the monitor
            monitor.record_state(f"task_{i}_completed")

        except Exception as e:
            print(f"Error: {e}")
            monitor.record_state(f"task_{i}_error")

        print()

        # Wait between tasks to see monitoring updates
        await asyncio.sleep(3)

    # Step 5: Demonstrate disconnecting and reconnecting
    print("Step 5: Demonstrating disconnect/reconnect...")

    # Disconnect agent memory
    monitor.disconnect_agent_memory()
    print("AgentMemory disconnected from monitor")
    await asyncio.sleep(2)

    # Reconnect agent memory
    monitor.connect_agent_memory(agent.memory)
    print("AgentMemory reconnected to monitor")
    print()

    # Run one more task
    print("Running final task after reconnection...")
    final_task = "What time is it?"
    result = await agent.process_command_async(final_task)
    print(f"Final task result: {result}")

    print()
    print("=" * 60)
    print("Demo completed!")
    print("The monitoring server is still running at: http://localhost:8000")
    print("You can connect other agents to it using monitor.connect_agent_memory(agent.memory)")
    print("Press Ctrl+C to stop the monitoring server")
    print("=" * 60)

    # Keep the monitoring server running
    try:
        while True:
            await asyncio.sleep(1)
    except KeyboardInterrupt:
        print("\nShutting down...")

def main():
    """Main entry point"""
    print("Starting AgentMemory Monitor Demo...")
    print("This demonstrates the loosely coupled monitoring design.")
    print()

    try:
        asyncio.run(demo_with_monitoring())
    except KeyboardInterrupt:
        print("\nDemo interrupted by user")
    except Exception as e:
        print(f"Demo error: {e}")
        import traceback
        traceback.print_exc()

if __name__ == "__main__":
    main()